﻿using System.Net.Http.Headers;

namespace wwm.LeetCodeHelper.Servers;

public partial class Helper
{
    private static HttpClient _httpClient;
    public static Credit credit { get; set; }
    public static Uris uris { get; set; }
    public static void setHttpClient(HttpClient client)
    {
        _httpClient = client;
    }
    public static void setCredit(Credit credit)
    {
        Helper.credit = credit;
    }
    public static void setUris(Uris uris)
    {
        Helper.uris = uris;
    }

    public static string parseCookie(string[] cookies, string key)
    {
        if (cookies == null || cookies.Length == 0)
        {
            return "";
        }
        for (int ix = 0; ix < cookies.Length; ix++)
        {
            var result = new Regex($@"{key}=(.+?);").Match(cookies[ix]).Value;
            /* helper.ts L29 原ts
              const result = cookies[ix].match(new RegExp(`${key}=(.+?);`));
                        if (result) {
                            return result[1] || "";
                        }
             */
            if (string.IsNullOrEmpty(result))
            {
                return string.IsNullOrEmpty(result) ? "" : result;
            }
        }
        return "";
    }

    public static string levelToName(int level)
    {
        return level switch
        {
            1 => "Easy",
            2 => "Medium",
            3 => "Hard",
            _ => "",
        };
    }

    public static ProblemStatus statusMap(string status)
    {
        return status switch
        {
            "ac" => ProblemStatus.Accept,
            "notac" => ProblemStatus.NotAccept,
            null => ProblemStatus.NotStart,
            _ => ProblemStatus.NotStart,
        };
    }

    public static ProblemDifficulty difficultyMap(int difficulty)
    {
        return difficulty switch
        {
            1 => ProblemDifficulty.Easy,
            2 => ProblemDifficulty.Medium,
            3 => ProblemDifficulty.Hard,
            _ => ProblemDifficulty.Easy
        };
    }

    public static SubmissionStatus submissionStatusMap(string submission)
    {
        return submission switch
        {
            "Accepted" or "10" => SubmissionStatus.Accepted,
            "Compile Error" or "11" => SubmissionStatus.CompileError,
            "Time Limit Exceeded" or "14" => SubmissionStatus.TimeLimitExceeded,
            "Wrong Answer" or "20" => SubmissionStatus.WrongAnswer,
            _ => SubmissionStatus.WrongAnswer
        };
    }

    public static async Task<HttpResponseMessage> HttpRequest(HttpRequestOptions options)
    {
        /* helper.ts L87
           return await Request({
                    method: options.method || "GET",
                    uri: options.url,
                    followRedirect: false,
                    headers: {
                        Cookie: Helper.credit ? `LEETCODE_SESSION=${Helper.credit.session};csrftoken=${Helper.credit.csrfToken}` : "",
                        "X-Requested-With": 'XMLHttpRequest',
                        "X-CSRFToken": Helper.credit ? Helper.credit.csrfToken : "",
                        Referer: options.referer || Helper.uris.base,
                    },
                    resolveWithFullResponse: options.resolveWithFullResponse || false,
                    form: options.form || null,
                    body: JSON.stringify(options.body) || "",
                });
         */
        Dictionary<string, string> headers = new Dictionary<string, string>();
        headers.Add("Cookie", Helper.credit != null ? $"LEETCODE_SESSION={Helper.credit.session};csrftoken={Helper.credit.csrfToken}" : "");
        headers.Add("X-Requested-With", "XMLHttpRequest");
        headers.Add("X-CSRFToken", Helper.credit != null ? Helper.credit.csrfToken : "");
        headers.Add("Referer", options.referer != null ? options.referer : Helper.uris.Base);
        HttpRequestHelper.SetHttpClient(_httpClient);
        return await HttpRequestHelper.Request(options, headers);
    }

    public static async Task<string> GraphQLRequest(GraphQLRequestOptions options)
    {
        if (_httpClient == null)
        {
            setHttpClient(new HttpClient());
        }
        _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Referer", options.referer != null ? options.referer : Helper.uris.Base);
        //_httpClient.DefaultRequestHeaders.Add("Referer", options.referer != null ? options.referer : Helper.uris.Base);
        var query = new StringContent(
           JsonSerializer.Serialize(new { query = options.query, variables = options.variables }),
           Encoding.UTF8,
           "application/json");
        query.Headers.ContentType = new MediaTypeHeaderValue("application/json");
        query.Headers.Add("Origin", options.origin != null ? options.origin : Helper.uris.Base);

        query.Headers.Add("Cookie", Helper.credit != null ? $"LEETCODE_SESSION={Helper.credit.session};csrftoken={Helper.credit.csrfToken}" : "");
        query.Headers.Add("X-Requested-With", "XMLHttpRequest");
        query.Headers.Add("X-CSRFToken", Helper.credit != null ? Helper.credit.csrfToken : "");
        var response = await _httpClient.PostAsync(uris.Graphql, query);
        response.EnsureSuccessStatusCode();
        string responseBody = await response.Content.ReadAsStringAsync();
        return responseBody;

    }

    public static void switchEndPoint(EndPoint endPoint)
    {
        if (endPoint == EndPoint.US)
        {
            var uris = Config.uri.us;
            Helper.setUris(uris);
            Leetcode.setUris(uris);
            //Problem.setUris(uris);
            //Submission.setUris(uris);
        }
        else if (endPoint == EndPoint.CN)
        {
            var uris = Config.uri.cn;
            Helper.setUris(uris);
            Leetcode.setUris(uris);
            //Problem.setUris(uris);
            //Submission.setUris(uris);
        }
    }
}